<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Service\User;

use App\Models\AdvanceCard;
use App\Models\BeanTransaction;
use App\Models\GoldBeanAccount;
use App\Models\GroupOrder;
use App\Models\OrderBeanRewards;
use App\Models\PointSetting;
use App\Models\User;
use App\Models\UserBeanPackages;
use App\Service\AdvanceCard\AdvanceCardService;
use App\Service\BaseService;
use App\Service\Notifications\NotificationService;
use App\Service\Pools\DividendService;
use App\Service\Setting\BeanSettingService;
use App\Service\Setting\GroupSettingService;
use Illuminate\Support\Facades\DB;

class BeanAccountService extends BaseService
{
    /**
     * 查询余额.
     * @param mixed $user_id
     */
    public function checkTheBalance($user_id): float
    {
        $account = GoldBeanAccount::query()->where('user_id', $user_id)->first();
        return $account->available_beans;
    }

    /**
     * 消费.
     *
     * @param mixed $user_id
     * @param mixed $amount
     * @param mixed $describe
     * @param mixed $transaction_type
     * @return false|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|void
     */
    public function consumption($user_id, $amount, $describe = 'KC通证减少', $transaction_type = 2)
    {
        $account = GoldBeanAccount::query()->where('user_id', $user_id)->first();
        if ($account->available_beans - $amount < 0) {
            return false;
        }
        if ($describe == 'KC通证减少') {
            $describe = 'KC通证减少:' . $amount;
        }
        $account->available_beans = bcsub($account->available_beans, $amount, 2);
        $account->consumed_beans = bcadd($account->consumed_beans, $amount, 2);
        $account->save();
        $this->transactionHistory($user_id, $amount, $account->available_beans, $transaction_type, $describe, 2);
        return $account;
    }

    public function isItSufficient($user_id, $amount): bool
    {
        $account = GoldBeanAccount::query()->where('user_id', $user_id)->first();
        if ($account->available_beans - $amount < 0) {
            return false;
        }
        return true;
    }

    /**
     * 拼单成功奖励KC通证.
     */
    public function initBeanReward(
        GroupOrder $order
    ) {
        DB::transaction(function () use ($order) {
            $setting = GroupSettingService::make()->getSetting();
            $contribution_value = $setting['contribution_value'];
            $bean = $setting['obtain'];
            $maxTotalDays = $setting['release_days'];
//            $bean = bcmul($order->amount, $setting['OBTAIN'], 2); //按照当前价格转换KC通证数量
            $countBeanRewards = OrderBeanRewards::query()
                ->where('user_id', $order->user_id)
                ->count('id');
//            //TODO 递增天数 9单加一天
            $addDays = (int) ($countBeanRewards / 9);
            $totalDays = bcadd(40, $addDays, 2);
            if ($totalDays > $maxTotalDays) {
                $totalDays = $maxTotalDays;
            }

            OrderBeanRewards::query()->create([
                'user_id' => $order->user_id,
                'batch_id' => $order->batch_id,
                'order_id' => $order->id,
                'total_reward_beans' => $bean,
                'daily_release_rate' => bcdiv(1, $totalDays, 4),
                'total_days' => $totalDays,
                'released_days' => $totalDays,
                'remaining_beans' => $bean,
                'contribution_value' => $contribution_value,
                'is_old' => 0,
            ]);
            $order->status = 3;
            $order->save();
            //发放券
            VoucherPackageService::make()->recharge($order->user_id, $order->amount);

            //中单分红池
            $pointSetting = PointSetting::query()->first();
            if ($pointSetting->on_group == 1) {
                SinglePoolService::make()->recharge($order->user_id, $pointSetting->group_pool_price);
            }

            //创建发货单 废弃
            //获取用户默认地址 废弃
//            $userAddress = UserAddress::query()
//                ->select('id')
//                ->where('user_id', $order->user_id)
//                ->where('is_default', 1)
//                ->first();
//            $order->shipment()->create([
//                'user_id' => $order->user_id,
//                'user_address_id' => $userAddress->id ?? 0,
//                'remark' => '拼单成功,创建发货单',
//                'status' => 0,
//            ]);
            $user = User::query()->find($order->user_id);
            $user->contribution_value += $contribution_value;
            $user->save();
            if ($order->is_card == 1) {
                //TODO 垫付卡
                $advanceCard = AdvanceCard::query()
                    ->where('user_id', $user->id)
                    ->find($order->card_id);
                AdvanceCardService::make()->consumptionAmount($order, $advanceCard);
            }

            PerformanceService::make()->userTreeRevenue($user, $order->amount, 2); //团队收益
            DividendService::make()->injectFunds($order->amount); //进入分红池
            PerformanceService::make()->performanceReward($user, $order->amount, 2); //业绩奖励
            NotificationService::make()->SystemNotify($user, '拼单成功');
        });
    }

    /**
     * 充值
     * @param mixed $user_id
     * @param mixed $amount
     * @param mixed $describe
     * @param mixed $is_refund
     * @param mixed $transaction_type
     * @return false|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|void
     */
    public function recharge($user_id, $amount, $describe = 'KC通证增加', $is_refund = false, $transaction_type = 1)
    {
        if ($amount < 0) {
            return false;
        }
        if ($describe == 'KC通证增加') {
            $describe = 'KC通证增加:' . $amount;
        }
        $account = GoldBeanAccount::query()->where('user_id', $user_id)->first();
        if (! $is_refund) {
            BeanSettingService::make()->increaseCirculation($amount);
            $account->total_beans += $amount;
        }
        $account->available_beans += $amount;
        $account->save();
        $this->transactionHistory($user_id, $amount, $account->available_beans, $transaction_type, $describe, 1);
        return $account;
    }

    /**
     * 每日释放拼单成功KC通证.
     */
    public function releaseTheGoldenBeansOfTheSpell()
    {
        $setting = BeanSettingService::make()->getSetting();
        $beanPrice = $setting['PRICE'];
        OrderBeanRewards::query()
            ->where('released_days', '>', 0)
            ->chunkById(100, function ($models) use ($beanPrice) {
                $models->each(function ($model) use ($beanPrice) {
                    DB::transaction(function () use ($model, $beanPrice) {
                        $_beans = bcmul($model->total_reward_beans, $model->daily_release_rate, 2);

                        if ($model->released_days == 1) {
                            $beans = $model->remaining_beans;
                            $model->remaining_beans = 0;
                        } else {
                            $model->remaining_beans = bcsub($model->remaining_beans, $_beans, 2);
                            $beans = $_beans;
                        }

                        if ($model->is_old == 0) {
                            $beans = bcdiv($_beans, $beanPrice, 2); //金本位
                            $msg = sprintf('释放KC通证%s,单价:%s,金本位:%s', $_beans, $beanPrice, $beans);
                        } else {
                            $msg = sprintf('今日释放拼单成功KC通证：%s', $beans);
                        }
                        --$model->released_days;

                        $model->save();
                        $model->source()->create([
                            'user_id' => $model->user_id,
                            'release_date' => now()->toDateString(),
                            'beans_released' => $beans,
                            'remaining_beans' => $model->remaining_beans,
                            'status' => 1,
                        ]);
                        $this->recharge($model->user_id, $beans, $msg);
                    });
                });
            });
    }

//    是否足够

    /**
     * 释放礼包KC通证.
     */
    public function releaseTheGiftPackGoldenBeans()
    {
        UserBeanPackages::query()
            ->where('status', 2)
            ->where('release_days', '>', 0)
            ->chunkById(100, function ($models) {
                $models->each(function ($model) {
                    return DB::transaction(function () use ($model) {
                        $bean = bcmul($model->total_beans, $model->daily_release_rate, 2);
                        if ($model->released_days == 1) {
                            $bean = $model->remaining_beans;
                            $model->remaining_beans = 0;
                        } else {
                            $model->remaining_beans = bcsub($model->remaining_beans, $bean, 2);
                        }

                        --$model->release_days;
                        $model->save();
                        $model->source()->create([
                            'user_id' => $model->user_id,
                            'release_date' => now()->toDateString(),
                            'beans_released' => $bean,
                            'remaining_beans' => $model->remaining_beans,
                            'status' => 1,
                        ]);
                        $this->recharge($model->user_id, $bean, "礼包今日释放:{$bean}");
                    });
                });
            });
    }

    /**
     * 交易记录.
     * @param mixed $user_id
     * @param mixed $amount
     * @param mixed $balance
     * @param mixed $transaction_type
     * @param mixed $describe
     * @param mixed $change_type
     */
    private function transactionHistory($user_id, $amount, $balance, $transaction_type, $describe, $change_type)
    {
        BeanTransaction::query()->create([
            'user_id' => $user_id,
            'amount' => $amount,
            'balance' => $balance,
            'transaction_type' => $transaction_type,
            'describe' => $describe,
            'status' => 2,
            'change_type' => $change_type,
        ]);

//        $user = User::query()->find($user_id);
//        if (filled($user)) {
//            NotificationService::make()->SystemNotify($user, $describe);
//        }
    }
}
